import json


class InfluxDBLineParser:
    def __init__(self):
        self.reset()

    def reset(self):
        self.state = "measurement"
        self.measurement = ""
        self.tags = {}
        self.fields = {}
        self.current_key = ""
        self.current_value = ""
        self.in_quoted_string = False
        self.escape_next = False

    def parse_line(self, line):
        self.reset()
        print(f"parse: {line}")
        for char in line:
            if self.state == "measurement":
                if char in [",", " "]:
                    self.state = "tag_key"
                else:
                    self.measurement += char
            elif self.state == "tag_key":
                if char == "=":
                    self.state = "tag_value"
                elif char != ",":
                    self.current_key += char
            elif self.state == "tag_value":
                if char in [" ", ","] and not self.in_quoted_string:
                    self.add_tag()
                    self.state = "field_key" if char == " " else "tag_key"
                else:
                    self.process_character_in_value(char)
            elif self.state == "field_key":
                if char == "=":
                    self.state = "field_value"
                elif char != " ":
                    self.current_key += char
            elif self.state == "field_value":
                if self.in_quoted_string:
                    self.process_character_in_value(char)
                    if char == '"' and not self.escape_next:
                        self.in_quoted_string = False
                elif char == '"' and not self.in_quoted_string:
                    self.in_quoted_string = True
                    self.process_character_in_value(char)
                elif char == "," and not self.in_quoted_string:
                    self.add_field()
                    self.state = "field_key"
                else:
                    self.process_character_in_value(char)

            self.escape_next = char == "\\"

        if self.state in ["tag_value", "tag_key"]:
            self.add_tag()
        elif self.state in ["field_value", "field_key"]:
            self.add_field()

        return self.measurement, self.tags, self.fields

    def process_character_in_value(self, char):
        if self.escape_next:
            self.current_value += char
        else:
            self.current_value += char

    def add_tag(self):
        self.tags[self.current_key.strip()] = self.current_value.strip()
        self.current_key = ""
        self.current_value = ""

    def add_field(self):
        if self.current_key and self.current_value:
            try:
                self.fields[self.current_key.strip()] = json.loads(
                    self.current_value.strip()
                )
            except ValueError as v:
                self.fields[self.current_key.strip()] = self.current_value.strip()
        self.current_key = ""
        self.current_value = ""
